/* *
? JavaScript 的寄生组合继承是一种常用的继承方式，它结合了寄生式继承和组合继承的优点，避免了它们的缺点。具体来说，寄生组合继承的实现过程如下：

? 1. 定义一个父类构造函数，其中包含需要继承的属性和方法。
? 2. 定义一个子类构造函数，其中通过调用父类构造函数来继承父类的属性，并将其作为子类的属性。
? 3. 使用 Object.create() 方法创建一个中间对象，将其原型指向父类的原型，从而实现继承父类的方法。
? 4. 将中间对象赋值给子类的原型，从而实现子类对父类属性和方法的继承。
? 5. 为子类添加其他属性和方法。
* */
//? 父类
function Animal(name) {
    this.name = name;
    this.type = 'mammal';
}

Animal.prototype.sayName = function() {
    console.log('My name is ' + this.name);
};
//? 定义一个子类构造函数
function Dog(name, breed) {
    //? 继承父类的属性
    Animal.call(this, name);
    //? 添加自己的属性
    this.breed = breed;
}

//? 使用寄生式继承继承Animal.prototype
//? Object.create()创建一个新对象并把该对象的原型设置为指定的原型(这段就相当于这个新对象在Dog的原型(Animal)上，其原型是Animal的原型)
//? 从而实现了继承 Animal 的方法
Dog.prototype = Object.create(Animal.prototype);
//? 将中间对象赋值给 Dog.prototype，从而实现了子类对父类属性和方法的继承
Dog.prototype.constructor = Dog;
Dog.prototype.sayBreed = function() {
    console.log('I am a ' + this.breed);
};
/*
? 最终相当于

?          sayName
? animal           {constructor,sayBreed}
?               dog{name,type(通过call添加),breed}
? 所以dog也就继承了sayName方法
 */


//? 使用子类
let myDog = new Dog('Max', 'Golden Retriever');
myDog.sayName(); // 'My name is Max'
myDog.sayBreed(); // 'I am a Golden Retriever'
console.log(myDog.__proto__)
